package leetcode_1001_1100;

import java.util.*;

public class LeeCode_1001 {
    public static void main(String[] args) {

    }
    private static int[] gridIllumination(int n, int[][] lamps, int[][] queries) {
        Map<Integer, Integer> rows = new HashMap<>();
        Map<Integer, Integer> cows = new HashMap<>();
        // \
        Map<Integer, Integer> x_1 = new HashMap<>();
        // /
        Map<Integer, Integer> x_2 = new HashMap<>();
        Map<Integer, Set<Integer>> map = new HashMap<>();
        for (int[] lamp : lamps) {
            int x = lamp[0], y = lamp[1];
            if (map.containsKey(x) && map.get(x).contains(y))
                continue;
            if (map.containsKey(x)){
                map.get(x).add(y);
            }else {
                Set<Integer> set = new HashSet<>();
                set.add(y);
                map.put(x, set);
            }
            rows.put(x, rows.getOrDefault(x, 0) + 1);
            cows.put(y, cows.getOrDefault(y, 0) + 1);
            int x1 = get1(n, x, y), x2 = get2(n, x, y);
            x_1.put(x1, x_1.getOrDefault(x1, 0) + 1);
            x_2.put(x2, x_2.getOrDefault(x2, 0) + 1);
        }
        int m = queries.length;
        int[] ans = new int[m];
        int[][] dirs = new int[][]{{-1,-1},{-1,1},{1,-1},{1,1},{1,0},{-1,0},{0,-1},{0,1},{0,0}};
        for (int i = 0; i < m; i++) {
            int x = queries[i][0], y = queries[i][1], x1 = get1(n, x, y), x2 = get2(n, x, y);
            if (rows.containsKey(x) || cows.containsKey(y) || x_1.containsKey(x1) || x_2.containsKey(x2)){
                ans[i] = 1;
            }
            for (int[] dir : dirs) {
                int nx = x + dir[0], ny = y + dir[1];
                if (nx < 0 || nx >= n || ny < 0 || ny >= n){
                    continue;
                }
                if (map.containsKey(nx) && map.get(nx).contains(ny)){
                    int n1 = get1(n, nx, ny), n2 = get2(n, nx, ny);
                    map.get(nx).remove(ny);
                    if (map.get(nx).isEmpty())
                        map.remove(nx);
                    del(rows, nx);
                    del(cows, ny);
                    del(x_1, n1);
                    del(x_2, n2);
                }
            }
        }
        return ans;
    }

    private static void del(Map<Integer, Integer> rows, int nx) {
        rows.put(nx, rows.get(nx) - 1);
        if (rows.get(nx) == 0)
            rows.remove(nx);
    }

    private static int get1(int n, int x, int y){
        int min = Math.min(x, y);
        x -= min;
        y -= min;
        if (x == 0){
            return n + y;
        }else {
            return n - x;
        }
    }
    private static int get2(int n, int x, int y){
        int min = Math.min(x, n - y - 1);
        x -= min;
        y += min;
        if (x == 0){
            return n * 2 - y - 1;
        }else {
            return n - x;
        }
    }
}